// 进行axios二次封装：使用请求和响应拦截器
import axios from 'axios'
// import { ElMessage } from 'element-plus'
import { useUserStore } from '@/store/modules/user'

// 第一步：利用axios的create方法，创建axios实例（create创建实例的同时可以配置基础路径、超时时间）
const request = axios.create({
  // 基础路径
  baseURL: import.meta.env.VITE_APP_BASE_API, // 基础路径会携带上/api，这是我们配置的环境变量
  // 超时时间
  timeout: 4000,
  retry: 0, //设置全局重试请求次数（最多重试几次请求）
  retryDelay: 1000, //设置全局请求间隔
})

// request实例添加请求与响应拦截器
request.interceptors.request.use((config) => {
  const userStore = useUserStore()
  // config配置对象，这个配置对象中有headers属性请求头，经常给服务器端携带公共参数
  if (userStore.token) {
    config.headers.token = userStore.token
  }
  // 返回配置对象
  // 可以进行进度条动画的播放
  return config
})

request.interceptors.response.use(
  (response) => {
    // 响应成功的回调
    // 可以进行数据的简化，进度条等动画的去除
    if(response.data) {
      response.config.retry = 0
    }
    return response.data
  },
  (error) => {

    // // 失败回调：处理http网络错误
    // // 定义一个变量，存储网络错误信息
    // let message = ''
    // // http状态码
    // let status = error.response.status
    // switch (status) {
    //   case 401:
    //     message = 'Token过期'
    //     break
    //   case 403:
    //     message = '无权访问'
    //     break
    //   case 404:
    //     message = '请求地址错误'
    //     break
    //   case 500:
    //     message = '服务器出现问题'
    //     break
    //   default:
    //     message = '网络出现问题'
    // }
    // // 提示错误信息
    // ElMessage({
    //   type: 'error',
    //   message,
    // })

    // return Promise.reject(error)

    // 超时处理
    const config = error.config
    if(!config || !config.retry){
      return Promise.reject(error)
    }

    // __retryCount用来记录当前是第几次发送请求
    config.__retryCount = config.__retryCount || 0

    // 如果当前发送的请求大于等于设置好的请求次数，不再发送请求，返回最终的错误信息
    if(config.__retryCount > config.retry) {
      if (error.message === "Network Error") {
        //message为"Network Error"代表断网了
        return Promise.reject({
          type: "warning",
          msg: "网络连接已断开，请检查网络",
        })
      } else if (error.message === "timeout of 10000ms exceeded") {
        //网太慢了，5秒内没有接收到数据，这里的10000ms对应上方timeout设置的值
        return Promise.reject({ type: "warning", msg: "请求超时，请检查网络" })
      } else {
        //除以上两种以外的所有错误，包括接口报错 400 500 之类的
        return Promise.reject({ type: "error", msg: "出现错误，请稍后再试" })
      }
    }

    // 记录请求次数加一
    config.__retryCount += 1

    // 设置请求间隔，在发送下一次请求之前停留一段时间，时间为上方设置好的请求时间
    const backOff = new Promise(function (resolve) {
      setTimeout(function() {
        resolve()
      }, config.retryDelay || 1)
    })

    // 再次发送请求
    return backOff.then(function() {
      return request(config)
    })
  },
)

export default request
